/* partoedi.js */

var partoedi = (function() {

    // {{{ globals
    // {{{ configPartoedi
    var configPartoedi =
        {
            
            "oneMB"                                         : 1048576 , 
            "oneGB"                                         : 1073741824, 

            "container" : {
                "padding"                                   : 10,
                "backgroundColor"                           : "#e0e0e0",       
                "borderStyle"                               : "solid",
                "borderWidth"                               : 2,
                "borderRadius"                              : 10
            },

            "overlay" :{
                "opacity"                                   : 0.1,
                "backgroundColor"                           : "#000000"
            },

            "create" :{
                "top"                                       : "10%",
                "left"                                      : "40%",
                "position"                                  : "fixed",
                "zIndex"                                    : 501,
                "width"                                     : 400,
                "height"                                    : 210,
                "borderColor"                               : "#000000",
                "borderWidth"                               : 2,
                "borderStyle"                               : "solid",
                "backgroundColor"                           : "#ffffff",
                "buttonTextAlign"                           : "right"
            },

            "edit" :{
                "top"                                       : "10%",
                "left"                                      : "40%",
                "position"                                  : "fixed",
                "zIndex"                                    : 501,
                "width"                                     : 400,
                "height"                                    : 150,
                "borderColor"                               : "#000000",
                "borderWidth"                               : 2,
                "borderStyle"                               : "solid",
                "backgroundColor"                           : "#ffffff",
                "buttonTextAlign"                           : "right"
            },

            "disk" : {
                "onSelected"                                : "#ff0000",

                "width"                                     : 0,
                "height"                                    : 80,
                "borderColor"                               : "#000000",
                "borderStyle"                               : "solid",
                "borderWidth"                               : 4,
                "borderRadius"                              : 10,
                "backgroundColor"                           : "#ffffff"
            },

            "primary" : {
                "onSelected"                                : "#ff0000",
                "minimumWidth"                              : 30,
                "dragBorderWidth"                           : 2,
                "dragBorderColor"                           : "#ff0000",
                "dragBorderMouseOverPointer"                : "pointer",
                "dragBorderMouseOutPointer"                 : "default",

                "borderColor"                               : "#000000",
                "borderStyle"                               : "solid",
                "borderWidth"                               : 4,
                "borderRadius"                              : 10,
                "backgroundColor"                           : "#ffffff",

                "textAlign"                                 : "center",
                "fontFamily"                                : "verdana",
                "fontColor"                                 : "#000000",
                "fontSize"                                  : 10
            },

            "extended" : {
                "onSelected"                                : "#ff0000",
                "minimumWidth"                              : 30,
                "dragBorderWidth"                           : 2,
                "dragBorderColor"                           : "#ff0000",
                "dragBorderMouseOverPointer"                : "pointer",
                "dragBorderMouseOutPointer"                 : "default",

                "borderColor"                               : "#000000",
                "borderStyle"                               : "solid",
                "borderWidth"                               : 4,
                "borderRadius"                              : 10,
                "backgroundColor"                           : "#ffffff",

                "textAlign"                                 : "center",
                "fontFamily"                                : "verdana",
                "fontColor"                                 : "#000000",
                "fontSize"                                  : 10
            },

            "logical" : {
                "onSelected"                                : "#ff0000",
                "minimumWidth"                              : 30,
                "dragBorderWidth"                           : 2,
                "dragBorderColor"                           : "#ff0000",
                "dragBorderMouseOverPointer"                : "pointer",
                "dragBorderMouseOutPointer"                 : "default",

                "borderColor"                               : "#000000",
                "borderStyle"                               : "solid",
                "borderWidth"                               : 4,
                "borderRadius"                              : 10,
                "backgroundColor"                           : "#ffffff",

                "textAlign"                                 : "center",
                "fontFamily"                                : "verdana",
                "fontColor"                                 : "#000000",
                "fontSize"                                  : 10
            },

            "title" : {
                "textAlign"                                 : "left",
                "fontFamily"                                : "verdana",
                "fontColor"                                 : "#00000",
                "fontSize"                                  : 10,
                "fontWeight"                                : "bold",
                "marginBottom"                              : 10
            },

            "button" : {
                "textAlign"                                 : "right",
                "marginTop"                                 : 5
            },

            "message" : {
                "m000"                                      : "Perhatian :",
                "m100"                                      : "Galat :"
            },

            "filesystem" : {
                "ext2"                                      : "Ext 2",
                "ext3"                                      : "Ext 3",
                "ext4"                                      : "Ext 4",
                "swap"                                      : "Swap"

            },

            "mountpoint" : {
                "root"                                      : "/root",
                "home"                                      : "/home"
            }
        }
    // }}}
    // {{{ dataParted
    var dataParted          =
        {
            "disk01" : {
                "path"                                      : "/dev/sda",
                "size"                                      : 250059350016,
                "model"                                     : "ATA WDC WD2500BEVS-0",
                "label"                                     : "msdos",
                "partitions" : [

                    {"id":-1,"parent":-1,"start":32256,"end":1048064,"size":1016320,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":1,"parent":-1,"start":1048576,"end":44757417472,"size":44756369408,"type":"DEVICE_PARTITION_TYPE_NORMAL","filesystem":"ext4","description":""},
                    {"id":-1,"parent":-1,"start":44757417984,"end":44758465024,"size":1047552,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":2,"parent":-1,"start":44758465536,"end":250058112512,"size":205299647488,"type":"DEVICE_PARTITION_TYPE_EXTENDED","filesystem":"","description":""},
                    {"id":-1,"parent":-1,"start":44758465536,"end":44758465536,"size":512,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":-1,"parent":-1,"start":44758466048,"end":44758466048,"size":512,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":8,"parent":-1,"start":44758466560,"end":50000297472,"size":5241831424,"type":"DEVICE_PARTITION_TYPE_LOGICAL","filesystem":"ext4","description":""},
                    {"id":-1,"parent":-1,"start":50000297984,"end":50001346048,"size":1048576,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":5,"parent":-1,"start":50001346560,"end":200000142848,"size":149998796800,"type":"DEVICE_PARTITION_TYPE_LOGICAL","filesystem":"ext4","description":""},
                    {"id":-1,"parent":-1,"start":200000143360,"end":200001191424,"size":1048576,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":6,"parent":-1,"start":200001191936,"end":201000484352,"size":999292928,"type":"DEVICE_PARTITION_TYPE_LOGICAL","filesystem":"linux-swap(v1)","description":""},
                    {"id":-1,"parent":-1,"start":201000484864,"end":201001166848,"size":682496,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":-1,"parent":-1,"start":201001167360,"end":201001532928,"size":366080,"type":"DEVICE_PARTITION_TYPE_FREESPACE","filesystem":"","description":""},
                    {"id":7,"parent":-1,"start":201001533440,"end":250058112512,"size":49056579584,"type":"DEVICE_PARTITION_TYPE_LOGICAL","filesystem":"ext4","description":""},
                    {"id":-1,"parent":-1,"start":250058113024,"end":250059349504,"size":1236992,"type":"DEVICE_PARTITION_TYPE_METADATA","filesystem":"","description":""}
                ]
            },

            "disk02" : {
                "path"                                      : "/dev/sdb",
                "size"                                      : 250059350016,
                "model"                                     : "ATA WDC WD2500BEVS-0",
                "label"                                     : "msdos",
                "partitions" : [
                ]
            }
        }
    // }}}
    var dataPartoedi        = {}
    // }}}

    // {{{ createDataPartoedi()
    var createDataPartoedi = function(data) {
        var __dataPartoedi = {}

        $.each(data, function(keyDisk, valueDisk) {
            __dataPartoedi[keyDisk]             = {}
            __dataPartoedi[keyDisk]["primary"]  = {}
            __dataPartoedi[keyDisk]["extended"] = {}
            __dataPartoedi[keyDisk]["logical"]  = {}
            __dataPartoedi[keyDisk]["scale"]    = 0;
            __dataPartoedi[keyDisk]["selected"] = "";

            __dataPartoedi[keyDisk]["size"]     = valueDisk["size"];
            __dataPartoedi[keyDisk]["label"]    = valueDisk["label"];
            __dataPartoedi[keyDisk]["path"]     = valueDisk["path"];
            __dataPartoedi[keyDisk]["model"]    = valueDisk["model"];

            $.each(valueDisk["partitions"], function (keyPartition, valuePartition) {
                if (valuePartition["id"] > 0) {
                    var typePartition = valuePartition["type"].split("_");
                    if (typePartition[3] == "NORMAL") {
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]               = {};
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["mountpoint"] = "";
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["starpx"]     = 0;
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["endpx"]      = 0;
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["status"]     = "";

                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["id"]         = valuePartition["id"];
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["start"]      = valuePartition["start"];
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["end"]        = valuePartition["end"];
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["size"]       = valuePartition["size"];
                        __dataPartoedi[keyDisk]["primary"]["primary" + valuePartition["id"]]["filesystem"] = valuePartition["filesystem"];
                    } else if (typePartition[3] == "EXTENDED") {
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]               = {};
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["startpx"]    = 0;
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["endpx"]      = 0;
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["status"]     = "";

                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["id"]         = valuePartition["id"];
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["start"]      = valuePartition["start"];
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["end"]        = valuePartition["end"];
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["size"]       = valuePartition["size"];
                        __dataPartoedi[keyDisk]["extended"]["extended" + valuePartition["id"]]["filesystem"] = valuePartition["filesystem"];
                    } else if (typePartition[3] == "LOGICAL") {
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]               = {};
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["mountpoint"] = "";
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["startpx"]    = 0;
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["endpx"]      = 0;
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["status"]     = "";

                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["id"]         = valuePartition["id"];
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["start"]      = valuePartition["start"];
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["end"]        = valuePartition["end"];
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["size"]       = valuePartition["size"];
                        __dataPartoedi[keyDisk]["logical"]["logical" + valuePartition["id"]]["filesystem"] = valuePartition["filesystem"];
                    }
                }
            });

        });

        return __dataPartoedi;
    }
    // }}}
    // {{{ initPage(data, config)
    var initPage = function(data, config) {
        $("body").append("<div id=\"partoediPage\"></div>");
        $("#partoediPage").append("<div id=\"partoediContainer\"></div>");

        // {{{ overlayForCreateAndEdit div
        $("#partoediPage").append("<div id=\"overlayForCreateAndEdit\"></div>");
        $("#overlayForCreateAndEdit").hide();

        $("#overlayForCreateAndEdit").css("top",                0);
        $("#overlayForCreateAndEdit").css("left",               0);
        $("#overlayForCreateAndEdit").css("position",           "fixed");
        $("#overlayForCreateAndEdit").css("z-index",            500);
        $("#overlayForCreateAndEdit").css("width",              "100%");
        $("#overlayForCreateAndEdit").css("height",             "100%");
        $("#overlayForCreateAndEdit").css("opacity",            config.overlay.opacity);
        $("#overlayForCreateAndEdit").css("background-color",   config.overlay.backgroundColor);
        // }}}
        // {{{ createPartition div
        $("#partoediPage").append("<div id=\"createPartition\"></div>");
        $("#createPartition").html("" +
            "<div id=\"typePartitionLabelCreate\">Type Partition :</div>" +
            "<div id=\"typePartitionInputCreate\">" +
                "<input name=\"typePartitionInputRadioCreate\" type=\"radio\" value=\"primary\">Primary</input>" +
                "<br />" + 
                "<input name=\"typePartitionInputRadioCreate\" type=\"radio\" value=\"extended\">Extended</input>" +
            "</div>" +

            "<div id=\"sizePartitionLabelCreate\">Size Partition :</div>" +
            "<div id=\"sizePartitionInputCreate\">" +
                "<input id=\"sizePartitionInputTextCreateId\" name=\"sizePartitionInputTextCreate\" type=\"text\" /> MB" +
            "</div>" +

            "<div id=\"filesystemPartitionLabelCreate\">Filesystem Partition :</div>" +
            "<div id=\"filesystemPartitionInputCreate\">" +
                "<select id=\"filesystemPartitionInputSelectCreateId\" name=\"filesystemPartitionInputSelectCreate\">" +
                "</select>" +
            "</div>" +

            "<div id=\"mountPartitionLabelCreate\">Mount Partition :</div>" +
            "<div id=\"mountPartitionInputCreate\">" +
                "<select id=\"mountPartitionInputSelectCreateId\" name=\"mountPartitionInputSelectCreate\">" +
                "</select>" +
            "</div>" +

            "<div id=\"confirmPartitionInputCreate\">" +
                "<button id=\"batalPartitionInputButtonCreate\"> Batal </button>" +
                "<button id=\"okPartitionInputButtonCreate\"> Ok </button>" +
            "</div>"
        );

        $.each(config.filesystem, function(key, value) {
            $("#filesystemPartitionInputSelectCreateId").append("<option value=\"" + key + "\">" + value + "</option>");
        });

        $.each(config.mountpoint, function(key, value) {
            $("#mountPartitionInputSelectCreateId").append("<option value=\"" + key + "\">" + value + "</option>");
        });

        $("#filesystemPartitionInputSelectCreateId").val([]);
        $("#mountPartitionInputSelectCreateId").val([]);

        $("#createPartition").hide();

        $("#createPartition").css("top",                config.create.top);
        $("#createPartition").css("left",               config.create.left);
        $("#createPartition").css("position",           config.create.position);
        $("#createPartition").css("z-index",            config.create.zIndex);
        $("#createPartition").css("width",              config.create.width);
        $("#createPartition").css("height",             config.create.height);
        $("#createPartition").css("background-color",   config.create.backgroundColor);
        $("#createPartition").css("border-color",       config.create.borderColor);
        $("#createPartition").css("border-width",       config.create.borderWidth);
        $("#createPartition").css("border-style",       config.create.borderStyle);

        $("#confirmPartitionInputCreate").css("text-align", config.create.buttonTextAlign);
        // }}}
        // {{{ editPartition div
        $("#partoediPage").append("<div id=\"editPartition\"></div>");
        $("#editPartition").html("" +
            "<div id=\"sizePartitionLabelEdit\">Size Partition :</div>" +
            "<div id=\"sizePartitionInputEdit\">" +
                "<input id=\"sizePartitionInputTextId\" name=\"sizePartitionInputText\" type=\"text\" /> MB" +
            "</div>" +

            "<div id=\"filesystemPartitionLabelEdit\">Filesystem Partition :</div>" +
            "<div id=\"filesystemPartitionInputEdit\">" +
                "<select id=\"filesystemPartitionInputSelectEditId\" name=\"filesystemPartitionInputSelectEdit\">" +
                "</select>" +
            "</div>" +

            "<div id=\"mountPartitionLabelEdit\">Mount Partition :</div>" +
            "<div id=\"mountPartitionInputEdit\">" +
                "<select id=\"mountPartitionInputSelectEditId\" name=\"mountPartitionInputSelectEdit\">" +
                "</select>" +
            "</div>" +

            "<div id=\"confirmPartitionInputEdit\">" +
                "<button id=\"batalPartitionInputButtonEdit\"> Batal </button>" +
                "<button id=\"okPartitionInputButtonEdit\"> Ok </button>" +
            "</div>"
        );

        $.each(config.filesystem, function(key, value) {
            $("#filesystemPartitionInputSelectEditId").append("<option value=\"" + key + "\">" + value + "</option>");
        });

        $.each(config.mountpoint, function(key, value) {
            $("#mountPartitionInputSelectEditId").append("<option value=\"" + key + "\">" + value + "</option>");
        });

        $("#editPartition").hide();

        $("#editPartition").css("top",                config.edit.top);
        $("#editPartition").css("left",               config.edit.left);
        $("#editPartition").css("position",           config.edit.position);
        $("#editPartition").css("z-index",            config.edit.zIndex);
        $("#editPartition").css("width",              config.edit.width);
        $("#editPartition").css("height",             config.edit.height);
        $("#editPartition").css("background-color",   config.edit.backgroundColor);
        $("#editPartition").css("border-color",       config.edit.borderColor);
        $("#editPartition").css("border-width",       config.edit.borderWidth);
        $("#editPartition").css("border-style",       config.edit.borderStyle);

        $("#confirmPartitionInputEdit").css("text-align", config.edit.buttonTextAlign);
        // }}}

        // {{{ resetCreateOverlay()
        var resetCreateOverlay = function() {
            $("input[name=typePartitionInputRadioCreate]:checked", "#typePartitionInputCreate").removeAttr("checked");
            $("#sizePartitionInputTextCreateId").val("");
            $("#filesystemPartitionInputSelectCreateId").val([]);
            $("#mountPartitionInputSelectCreateId").val([]);
        }
        // }}}
        // {{{ resetEditOverlay()
        var resetEditOverlay = function() {
            $("#sizePartitionInputTextId").val("");
            $("#filesystemPartitionInputSelectEditId").val([]);
            $("#mountPartitionInputSelectEditId").val([]);
        }
        // }}}

        $.each(data, function(key, value) {
            $("#partoediContainer").append(" <div id=\"" + key  + "\"><div>");

            $("#" + key).html("" +
                "<div id=\"" + key + "Title\"></div>" +
                "<div id=\"" + key + "Container\"></div>" + 
                "<div id=\"" + key + "Button\"></div>" + 
                "<div id=\"" + key + "Info\"></div>"
            );
            
            $("#" + key).css("background-color", config.container.backgroundColor);
            $("#" + key).css("border-width",     config.container.borderWidth);
            $("#" + key).css("border-style",     config.container.borderStyle);
            $("#" + key).css("border-color",     config.container.borderColor);
            $("#" + key).css("border-radius",    config.container.borderRadius);
            $("#" + key).css("padding",          config.container.padding);

            $("#" + key + "Title").html(value.model + " " + value.path + " " + Math.round(value.size / config.oneGB) + " GB");

            $("#" + key + "Title").css("margin-bottom", config.title.marginBottom);
            $("#" + key + "Title").css("text-align",    config.title.textAlign);
            $("#" + key + "Title").css("font-family",   config.title.fontFamily);
            $("#" + key + "Title").css("color",         config.title.fontColor);
            $("#" + key + "Title").css("font-size",     config.title.fontSize);
            $("#" + key + "Title").css("font-weight",   config.title.fontWeight);

            config.disk.width = $("#" + key + "Container").width();
            value.scale = value.size / config.disk.width; 

            // TODO: use image for buttons
            // 

            $("#" + key + "Button").html("<button id=\"minusButton"+ key + "\" >D</button> <button id=\"plusButton" + key + "\">A</button>");

            $("#" + key + "Button").css("margin-top",  config.button.marginTop);
            $("#" + key + "Button").css("text-align",  config.button.textAlign);

            $("#minusButton" + key).attr("disabled","disabled");
            $("#plusButton" + key).attr("disabled","disabled");

            // TODO: what to do ?
            // 

            $("#minusButton" + key).click(function() { 
                console.log(dataPartoedi);
                value.kineticjs["layer" + key + value.selected].remove();
                value.kineticjs["layer" + key + value.selected] = "";
                value[value.selected.replace(/\d+/, "")][value.selected] = "";
                value.selected = "";
            });

            // TODO: what to do ?
            //

            $("#plusButton" + key).click(function() { 
                if (value.selected.indexOf("extended") == 0) { 
                    $("#createPartition").css("height", (config.create.height - 60));
                    $("input[name=typePartitionInputRadioCreate][value=extended]", "#typePartitionInputCreate").attr("checked", "checked");
                    $("#typePartitionLabelCreate").hide();
                    $("#typePartitionInputCreate").hide();
                } else {
                    $("#createPartition").css("height", config.create.height);
                    $("input[name=typePartitionInputRadioCreate][value=extended]", "#typePartitionInputCreate").removeAttr("checked");
                    $("#typePartitionLabelCreate").show();
                    $("#typePartitionInputCreate").show();
                };
                $("#overlayForCreateAndEdit").show(); 
                $("#createPartition").show();
            });

            $("#partoediContainer").append(" <div id=\"brDiv\"><br /><div>");
        });

        $("#batalPartitionInputButtonCreate").click(function() { 
            resetCreateOverlay();
            $("#createPartition").hide(); 
            $("#overlayForCreateAndEdit").hide(); 
        });

        $("#okPartitionInputButtonCreate").click(function() { 
            alert($("input[name=typePartitionInputRadioCreate]:checked", "#typePartitionInputCreate").val());
            alert($("#sizePartitionInputTextCreateId").val());
            alert($("#filesystemPartitionInputSelectCreateId").val());
            alert($("#mountPartitionInputSelectCreateId").val());

            resetCreateOverlay();
            $("#createPartition").hide(); 
            $("#overlayForCreateAndEdit").hide(); 
        });
    }
    // }}}

    // {{{ initDisk(data, config)
    var initDisk = function(data, config) {
        $.each(data, function(key, value) {
            value.kineticjs           = {};
            value.kineticjs.container = key + "Container";

            value.kineticjs.stage = new Kinetic.Stage({
                container : value.kineticjs.container,
                width     : config.disk.width,
                height    : config.disk.height
            });
           
            value.kineticjs["layer" + key] = new Kinetic.Layer();

            var disk = new Kinetic.Rect({
                x            : config.disk.borderWidth,
                y            : config.disk.borderWidth,
                width        : config.disk.width - (2 * config.disk.borderWidth),
                height       : config.disk.height - (2 * config.disk.borderWidth),
                fill         : config.disk.backgroundColor,
                stroke       : config.disk.borderColor,
                strokeWidth  : config.disk.borderWidth,
                cornerRadius : config.disk.borderRadius
            });

            value.kineticjs["layer" + key].add(disk);

            disk.on("click", function() { 
                disk.setStroke(config.disk.onSelected);

                if (value.selected) {
                    if (value.selected.replace(/\d+/, "") == "disk") {
                        value.kineticjs["layer" + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                        value.kineticjs["layer" + value.selected].draw();
                    } else {
                        value.kineticjs["layer" + key + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                        value.kineticjs["layer" + key + value.selected].draw();
                    }
                }

                if (value.selected == key) { value.selected = ""; } else { value.selected = key; }
                if (value.selected) { 
                    $("#minusButton" + key).attr("disabled", "disabled"); 

                    // TODO: msdos <= 4 partition 
                    // you can only create 4 primary or logical partition

                    $("#plusButton" + key).removeAttr("disabled");
                } else { 
                    $("#minusButton" + key).attr("disabled", "disabled"); 
                    $("#plusButton" + key).attr("disabled", "disabled"); 
                }

                value.kineticjs["layer" + key].draw();
            });

            value.kineticjs.stage.add(value.kineticjs["layer" + key]);
        });
    };
    // }}}
    // {{{ initPartition(data, config, type)
    var initPartition = function(data, config, type) {

        // {{{ getMaxBorder()
        var getMaxBorder = function(diskNumber, typePartition, endpx) {
            var nearest = config.disk.width;

            if (typePartition == "logical") {
                $.each(data[diskNumber][typePartition], function(key, value) {
                    if (value.startpx < endpx) { return true; };
                    nearest = value.startpx < nearest ? value.startpx : nearest;
                });
            } else {
                $.each(data[diskNumber]["primary"], function(key, value) {
                    if (value.startpx < endpx) { return true; };
                    nearest = value.startpx < nearest ? value.startpx : nearest;
                });

                $.each(data[diskNumber]["extended"], function(key, value) {
                    if (value.startpx < endpx) { return true; };
                    nearest = value.startpx < nearest ? value.startpx : nearest;
                });
            }

            return nearest;
        }
        // }}}

        $.each(data, function(key, value) {
            $.each(value[type], function(keyPartition, valuePartition) {

                valuePartition.startpx = Math.round(valuePartition.start / value.scale);
                valuePartition.endpx   = Math.round(valuePartition.end / value.scale);
            });
        });

        $.each(data, function(key, value) {
            $.each(value[type], function(keyPartition, valuePartition) {

                // TODO: be carefull with your data. small partition will not be shown
                //

                if ((valuePartition.endpx - valuePartition.startpx) < config[type].minimumWidth) { return true; }

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                value.kineticjs["layer" + key + keyPartition] = new Kinetic.Layer();

                if (type == "logical") {
                    var partition = new Kinetic.Rect({
                        x            : valuePartition.startpx + (2 * config.disk.borderWidth) + (2 * config.logical.borderWidth) + (2 * config[type].borderWidth),
                        y            : (2 * config.disk.borderWidth) + (2 * config.logical.borderWidth),
                        width        : (valuePartition.endpx - valuePartition.startpx) - (4 * config.disk.borderWidth) - (4 * config.logical.borderWidth) - 8,
                        height       : config.disk.height - (4 * config.disk.borderWidth) - (4 * config.logical.borderWidth),
                        fill         : config[type].backgroundColor,
                        stroke       : config[type].borderColor,
                        strokeWidth  : config[type].borderWidth,
                        cornerRadius : config[type].borderRadius
                    });
                } else {
                    var partition = new Kinetic.Rect({
                        x            : valuePartition.startpx + (2 * config.disk.borderWidth) + 2,
                        y            : (2 * config.disk.borderWidth) + 2,
                        width        : (valuePartition.endpx - valuePartition.startpx) - (4 * config.disk.borderWidth) - 4,
                        height       : config.disk.height - (4 * config.disk.borderWidth) - 4,
                        fill         : config[type].backgroundColor,
                        stroke       : config[type].borderColor,
                        strokeWidth  : config[type].borderWidth,
                        cornerRadius : config[type].borderRadius
                    });
                }

                value.kineticjs["layer" + key + keyPartition].add(partition);

                partition.on("click", function() { 
                    partition.setStroke(config[type].onSelected);

                    if (value.selected) { 
                        if (value.selected.replace(/\d+/, "") == "disk") {
                            value.kineticjs["layer" + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                            value.kineticjs["layer" + value.selected].draw();
                        } else {
                            value.kineticjs["layer" + key + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                            value.kineticjs["layer" + key + value.selected].draw();
                        }
                    }

                    if (value.selected == keyPartition) { value.selected = ""; } else { value.selected = keyPartition; }
                    if (value.selected) { 
                        $("#minusButton" + key).removeAttr("disabled"); 

                        if (type == "extended") {
                            if (! $.isEmptyObject(value.logical)) { $("#minusButton" + key).attr("disabled", "disabled"); }

                            // TODO: check if it still allowed to create a new partition
                            // extended partition already in maximum size

                            $("#plusButton" + key).removeAttr("disabled");

                        } else {
                            $("#plusButton" + key).attr("disabled", "disabled");
                        }

                    } else { 
                        $("#minusButton" + key).attr("disabled", "disabled"); 
                        $("#plusButton" + key).attr("disabled", "disabled");
                    }

                    value.kineticjs["layer" + key + keyPartition].draw();
                });

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                if ( (type != "extended") || ( (type == "extended") && ($.isEmptyObject(value.logical) ) ) ) {
                    var partitionDragBorder = new Kinetic.Rect({
                        x              : partition.getX() + partition.getWidth() - config[type].dragBorderWidth - config[type].borderWidth,
                        y              : partition.getY() + config[type].borderRadius,
                        width          : config[type].dragBorderWidth,
                        height         : partition.getHeight() - (2 * config[type].borderRadius), 
                        fill           : config[type].backgroundColor,
                        draggable      : true,
                        dragBoundFunc  : function(pos) {
                            var minLeft  = partition.getX() + config[type].minimumWidth;

                            var maxBorder = getMaxBorder(key, type, (data[key][type][keyPartition]["endpx"]))

                            if (type == "logical") {
                                var maxRight  = maxBorder - (2 * config.disk.borderWidth) - (2 * config[type].borderWidth);
                            } else {
                                var maxRight  = maxBorder - (2 * config.disk.borderWidth) - 2;
                            }

                            var xValue = pos.x;

                            if (pos.x < minLeft) {
                                xValue = minLeft;
                            } else if (pos.x > maxRight) {
                                xValue = maxRight;
                            }

                            return {
                                x : xValue,
                                y : this.getAbsolutePosition().y
                            }
                        }
                    }); 

                    value.kineticjs["layer" + key + keyPartition].add(partitionDragBorder);

                    partitionDragBorder.on("mouseover", function() { 
                        document.body.style.cursor = config[type].dragBorderMouseOverPointer;
                        partitionDragBorder.setFill(config[type].dragBorderColor);
                        value.kineticjs["layer" + key + keyPartition].draw();
                    });

                    partitionDragBorder.on('mouseout',  function() { 
                        document.body.style.cursor = config[type].dragBorderMouseOutPointer;
                        partitionDragBorder.setFill(config[type].backgroundColor);
                        value.kineticjs["layer" + key + keyPartition].draw();
                    });

                    partitionDragBorder.on('dragmove',  function() {
                        partitionDragBorder.setFill(config[type].dragBorderColor);
                        partition.setWidth(partitionDragBorder.getX() - partition.getX());
                        partitionDragBorder.setX(partition.getX() + partition.getWidth() - config[type].dragBorderWidth - config[type].borderWidth);

                        partitionInfo.setText(value.path + valuePartition.id + " " + valuePartition.filesystem + "\n" + Math.round(partition.getWidth() * value.scale / config.oneGB) + " GB");
                        partitionInfo.setX(partition.getX() + 0.5 * (partition.getWidth() - partitionInfo.getWidth()));
                        partitionInfo.setY(partition.getY() + 0.5 * (partition.getHeight() - partitionInfo.getHeight()));
                    });

                    partitionDragBorder.on('dragend',  function() {
                        partitionDragBorder.setFill(config[type].backgroundColor);
                        value.kineticjs["layer" + key + keyPartition].draw();
                        
                    });
                }

// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                if ( (type != "extended") || ( (type == "extended") && ($.isEmptyObject(value.logical) ) ) ) {

                    var partitionInfo = new Kinetic.Text({
                        text            : value.path + valuePartition.id + " " + valuePartition.filesystem + "\n" + Math.round(partition.getWidth() * value.scale / config.oneGB) + " GB",
                        align           : config[type].textAlign,
                        fontSize        : config[type].fontSize,
                        fontFamily      : config[type].fontFamily,
                        textFill        : config[type].fontColor
                    });

                    partitionInfo.setX(partition.getX() + 0.5 * (partition.getWidth() - partitionInfo.getWidth()));
                    partitionInfo.setY(partition.getY() + 0.5 * (partition.getHeight() - partitionInfo.getHeight()));

                    value.kineticjs["layer" + key + keyPartition].add(partitionInfo);

                    partitionInfo.on("mouseover", function() { 
                        partitionInfo.setTextFill("#ff0000");
                        value.kineticjs["layer" + key + keyPartition].draw();
                    });

                    partitionInfo.on("mouseout", function() {
                        partitionInfo.setTextFill(config[type].fontColor);
                        value.kineticjs["layer" + key + keyPartition].draw();
                    });

                    partitionInfo.on("click", function() { 

                        partition.setStroke(config[type].onSelected);

                        if (value.selected) { 
                            if (value.selected.replace(/\d+/, "") == "disk") {
                                value.kineticjs["layer" + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                                value.kineticjs["layer" + value.selected].draw();
                            } else {
                                value.kineticjs["layer" + key + value.selected]["children"][0]["attrs"]["stroke"] = config[value.selected.replace(/\d+/, "")].borderColor; 
                                value.kineticjs["layer" + key + value.selected].draw();
                            }
                        }

                        if (value.selected == keyPartition) { value.selected = ""; } else { value.selected = keyPartition; }
                        if (value.selected) { 
                            $("#minusButton" + key).removeAttr("disabled"); 

                            if (type == "extended") {
                                if (! $.isEmptyObject(value.logical)) { $("#minusButton" + key).attr("disabled", "disabled"); }

                                // TODO: check if it still allowed to create a new partition
                                // extended partition already in maximum size

                                $("#plusButton" + key).removeAttr("disabled");

                            } else {
                                $("#plusButton" + key).attr("disabled", "disabled");
                            }

                        } else { 
                            $("#minusButton" + key).attr("disabled", "disabled"); 
                            $("#plusButton" + key).attr("disabled", "disabled");
                        }

                        value.kineticjs["layer" + key + keyPartition].draw();

                        $("#overlayForCreateAndEdit").show();
                        $("#editPartition").show();

                        var __oldSizePartition = Math.round(partition.getWidth() * value.scale / config.oneMB);

                        $("#sizePartitionInputTextId").val(__oldSizePartition);
                        $("#filesystemPartitionInputSelectEditId").val(valuePartition.filesystem);
                        
                        if (valuePartition.mount) { $("#mountPartitionInputSelectEditId").val(valuePartition.mount); } else { $("#mountPartitionInputSelectEditId").val([]);}

                        $("#batalPartitionInputButtonEdit").click(function() { $("#editPartition").hide(); $("#overlayForCreateAndEdit").hide(); });
                        $("#okPartitionInputButtonEdit").click(function() { 

                            if ($("#sizePartitionInputTextId").val() != __oldSizePartition) {
                                valuePartition.end = valuePartition.start + Math.round($("#sizePartitionInputTextId").val() * config.oneMB);
                                valuePartition.endpx   = Math.round(valuePartition.end / value.scale);

                                if (type == "logical") {
                                    partition.setWidth((valuePartition.endpx - valuePartition.startpx) - (4 * config.disk.borderWidth) - (4 * config.logical.borderWidth) - 8);
                                } else {
                                    partition.setWidth((valuePartition.endpx - valuePartition.startpx) - (4 * config.disk.borderWidth) - 4);
                                }
                            }

                            valuePartition.filesystem = $("#filesystemPartitionInputSelectEditId").val();
                            valuePartition.mount      = $("#mountPartitionInputSelectEditId").val();

                            partitionInfo.setText(value.path + valuePartition.id + " " + valuePartition.filesystem + "\n" + Math.round(partition.getWidth() * value.scale / config.oneGB) + " GB");
                            partitionInfo.setX(partition.getX() + 0.5 * (partition.getWidth() - partitionInfo.getWidth()));
                            partitionInfo.setY(partition.getY() + 0.5 * (partition.getHeight() - partitionInfo.getHeight()));

                            value.kineticjs["layer" + key + keyPartition].draw();

                            $("#editPartition").hide();
                            $("#overlayForCreateAndEdit").hide(); 

                        });
                    });
                }
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                value.kineticjs.stage.add(value.kineticjs["layer" + key + keyPartition]);
            });
        });
    }
    // }}}

    // {{{ main()
    var main = function() {
        dataPartoedi   = createDataPartoedi(dataParted);

        initPage(dataPartoedi, configPartoedi);
        initDisk(dataPartoedi, configPartoedi);

        initPartition(dataPartoedi, configPartoedi, "primary");
        initPartition(dataPartoedi, configPartoedi, "extended");
        initPartition(dataPartoedi, configPartoedi, "logical");

        // debugger :D
        //console.log(configPartoedi);
        //console.log(dataParted);
        //console.log(dataPartoedi);
    }
    // }}}

    return {
        main : main
    }

}).apply();

$(document).ready(function() {
    partoedi.main();

    $(window).resize( function() {
        $("#partoediPage").remove();
        partoedi.main();
    });
});
